/*
 * ElevatorDestinationComunicator.cpp
 *
 */

#include "ElevatorComunicator.h"

using namespace std;

ElevatorComunicator::ElevatorComunicator(int floorAmmount,char id,std::string keyGeneratorPath):
		m_callComunicator(floorAmmount*2),m_semaphore(keyGeneratorPath,id,1)
{
	m_id = id;
	m_floorAmmount = floorAmmount;
	m_callComunicator.create(keyGeneratorPath, id);
	m_elevatorStatusCommunicator.create(keyGeneratorPath, id+ELEVATOR_STATUS_INITIAL_KEY);
}


ElevatorComunicator::~ElevatorComunicator()
{
}

void ElevatorComunicator::setHallCalls(FloorIdentifierList floorList)
{
	FloorIdentifierList::iterator it;
	unsigned int i;

	m_semaphore.dec();

	//Recorro la lista de pisos,
	for(i= 0;i < m_floorAmmount;i++)
		m_callComunicator.write(false,i);

	for(it = floorList.begin(); it != floorList.end(); it++)
		m_callComunicator.write(true,*it);

	m_semaphore.inc();
}

FloorIdentifierList ElevatorComunicator::getHallCalls()
{
	FloorIdentifierList floorList;
	bool currentFloorHasPassengers;
	unsigned int i;

	m_semaphore.dec();

	for( i=0;i < m_floorAmmount;i++)
	{
		currentFloorHasPassengers = m_callComunicator.read(i);

		if(currentFloorHasPassengers)
			floorList.push_back(i);
	}

	m_semaphore.inc();

	return floorList;
}

void ElevatorComunicator::setAllCalls(FloorIdentifierList floorList)
{
	FloorIdentifierList::iterator it;
	unsigned int i;

	m_semaphore.dec();

	//Recorro la lista de pisos,
	for(i= 0;i < m_floorAmmount;i++)
		m_callComunicator.write(false,m_floorAmmount+i);

	for(it = floorList.begin(); it != floorList.end(); it++)
		m_callComunicator.write(true,m_floorAmmount+*it);

	m_semaphore.inc();
}

FloorIdentifierList ElevatorComunicator::getAllCalls()
{
	FloorIdentifierList floorList;
	bool currentFloorHasPassengers;
	unsigned int i;

	m_semaphore.dec();

	for( i=0;i < m_floorAmmount;i++)
	{
		currentFloorHasPassengers = m_callComunicator.read(m_floorAmmount+i);

		if(currentFloorHasPassengers)
			floorList.push_back(i);
	}

	m_semaphore.inc();

	return floorList;
}

void ElevatorComunicator::setMovementStatus(FloorIdentifier floorId, ElevatorStatusEnum direction)
{
	ElevatorStatus status;

	m_semaphore.dec();
	status = m_elevatorStatusCommunicator.read();

	status.m_currentDirection = direction;
	status.m_currentFloor = floorId;

	m_elevatorStatusCommunicator.write(status);
	m_semaphore.inc();
}

void ElevatorComunicator::setElevatorStatus(ElevatorStatus &status)
{
	m_semaphore.dec();
	m_elevatorStatusCommunicator.write(status);
	m_semaphore.inc();
}

ElevatorStatus ElevatorComunicator::getElevatorStatus()
{
	ElevatorStatus status;

	m_semaphore.dec();
	status = m_elevatorStatusCommunicator.read();
	m_semaphore.inc();

	return status;
}

void ElevatorComunicator::releaseResources()
{
	m_semaphore.destroy();
	m_elevatorStatusCommunicator.release();
	m_callComunicator.release();
}
